package uns.fit.gis.alg;

import java.io.IOException;
import java.util.Vector;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;

import uns.fit.gis.Util;
import uns.fit.gis.mapdrawer.MapCanvas;
import uns.fit.gis.mapobj.Crossroads;
import uns.fit.gis.mapobj.Segment;

public class RouteTrackingThread extends Thread {
	private MapCanvas mapCanvas;
	private Vector segments;
	private Vector cross;

	private int currentX;
	private int currentY;
	
	public static Image warningSign;
	private static Graphics g;
	private static Sprite directionSprite;
	
	public RouteTrackingThread(MapCanvas mapCanvas) {
		this.mapCanvas = mapCanvas;
		currentX = MapCanvas.currentX;
		currentY = MapCanvas.currentY;
		warningSign = Image.createImage(mapCanvas.getWidth(), 50);
		g = warningSign.getGraphics();
		try {
			directionSprite = new Sprite(Image.createImage("/direction.png"), 50, 50);
			directionSprite.setFrame(0);
			directionSprite.setPosition(0, 0);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.segments = MapCanvas.alg.getSegmentTrace();
		this.cross = MapCanvas.alg.getCrossroadsTrace();
	}
	
	private int prevSegmentId = -1;
	public void run() {
		while(!MapCanvas.stopGPSThread) {
			//System.out.println("TRACKING");
			State state = trackOnRoute(MapCanvas.currentX, MapCanvas.currentY);
			state.doService();
		}
	}

	public State trackOnRoute(int x, int y) {
		currentX = x;
		currentY = y;
		boolean flag = false;
        int currentSegmentId = Util.findClosestSegment(MapCanvas.currentX, MapCanvas.currentY);
	    if(prevSegmentId != currentSegmentId) {
	        int nextSegmentId = currentSegmentId;
			for(int i = 0; i < segments.size(); i ++) {
				/*
				 * Khi chay vao 1 segment khong nam trong danh sach segment trong route
				 * thi bao chay sai duong.
				 * Bi loi trong truong hop da chay ngang qua (khoi) dich,
				 * vi van con tren segment trong route nen khong bao sai duong.
				 */
				if(((Segment)segments.elementAt(i)).getId() == currentSegmentId) {
					flag = true;
					if(i != segments.size() - 1)
						nextSegmentId = ((Segment)segments.elementAt(i + 1)).getId();
	                break;
				}
			}
			if(!flag)
				return new WrongRouteState();
			/*
			for(int i = 0; i < cross.size(); i ++) {
				
				Crossroads nearCross = (Crossroads)cross.elementAt(i);
				double d = Util.calculateDistancePoint2Point(currentX, currentY, nearCross.getX(), nearCross.getY());
				//Gan crossroads va TIEN VE crossroads
				if(d < State.TRACKING_ON_ROUTE_MIN_DISTANCE) {// && d < Util.calculateDistancePoint2Point(currentX, currentY, nearCross.getX(), nearCross.getY())) {
					directionSprite.paint(g);
					return new CrossroadsState(nearCross, i);
				}
			}
			*/
			if(currentSegmentId != -1) {
				int x0, y0, x1, y1, x2, y2;
				Segment curSeg = MapCanvas.segments[currentSegmentId];
				Segment nextSeg = MapCanvas.segments[nextSegmentId];
				if(curSeg.getPathId() != nextSeg.getPathId()) {
					if(nextSeg.getCross0() == curSeg.getCross0()) {
						x0 = MapCanvas.cross[curSeg.getCross1()].getX();
						y0 = MapCanvas.cross[curSeg.getCross1()].getY();
						x1 = MapCanvas.cross[curSeg.getCross0()].getX();
						y1 = MapCanvas.cross[curSeg.getCross0()].getY();
						x2 = MapCanvas.cross[nextSeg.getCross1()].getX();
						y2 = MapCanvas.cross[nextSeg.getCross1()].getY();
					}
					else if(nextSeg.getCross1() == curSeg.getCross1()) {
						x0 = MapCanvas.cross[curSeg.getCross0()].getX();
						y0 = MapCanvas.cross[curSeg.getCross0()].getY();
						x1 = MapCanvas.cross[curSeg.getCross1()].getX();
						y1 = MapCanvas.cross[curSeg.getCross1()].getY();
						x2 = MapCanvas.cross[nextSeg.getCross0()].getX();
						y2 = MapCanvas.cross[nextSeg.getCross0()].getY();
					}
					else if(nextSeg.getCross0() == curSeg.getCross1()) {
						x0 = MapCanvas.cross[curSeg.getCross0()].getX();
						y0 = MapCanvas.cross[curSeg.getCross0()].getY();
						x1 = MapCanvas.cross[curSeg.getCross1()].getX();
						y1 = MapCanvas.cross[curSeg.getCross1()].getY();
						x2 = MapCanvas.cross[nextSeg.getCross1()].getX();
						y2 = MapCanvas.cross[nextSeg.getCross1()].getY();
					}
					else { //(segment.getCross1() == prevSegment.getCross0()
						x0 = MapCanvas.cross[curSeg.getCross1()].getX();
						y0 = MapCanvas.cross[curSeg.getCross1()].getY();
						x1 = MapCanvas.cross[curSeg.getCross0()].getX();
						y1 = MapCanvas.cross[curSeg.getCross0()].getY();
						x2 = MapCanvas.cross[nextSeg.getCross0()].getX();
						y2 = MapCanvas.cross[nextSeg.getCross0()].getY();
					}
		            String dir = Util.getTurningDirection(x0, y0, x1, y1, x2, y2);
		            directionSprite.setFrame(dir.equalsIgnoreCase(Util.TURN_LEFT) ? 0 : 2);
		            String pathName = Util.decodeCharacters(MapCanvas.paths[MapCanvas.segments[nextSegmentId].getPathId()].getName());
		            //System.out.println(pathName);
		            g.setColor(221, 238, 187);
					g.fillRect(0, 0, mapCanvas.getWidth(), 50);
		            directionSprite.paint(g);
		            g.setColor(0, 0, 0);
		            g.drawString(pathName, 60, 30, Graphics.BOTTOM | Graphics.LEFT);
				}
				else {
					directionSprite.setFrame(1);
		            String pathName = Util.decodeCharacters(MapCanvas.paths[MapCanvas.segments[nextSegmentId].getPathId()].getName());
		            //System.out.println(pathName);
		            g.setColor(221, 238, 187);
					g.fillRect(0, 0, mapCanvas.getWidth(), 50);
		            directionSprite.paint(g);
		            g.setColor(0, 0, 0);
		            g.drawString(pathName, 60, 30, Graphics.BOTTOM | Graphics.LEFT);
				}
			}
			
			prevSegmentId = currentSegmentId;
	    }
		return new NormalState();
	}
	
	public RouteTrackingThread() {
		// TODO Auto-generated constructor stub
	}
	
	public RouteTrackingThread(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

	public RouteTrackingThread(Runnable target) {
		super(target);
		// TODO Auto-generated constructor stub
	}

	public RouteTrackingThread(Runnable target, String name) {
		super(target, name);
		// TODO Auto-generated constructor stub
	}

}
